<template>
  <DropdownMenu
    placement="right-start"
    trigger="click"
    :hide-on-click="true"
    @visible-change="handleMenuVisibleChange"
  >
    <div class="editor-drag-handle__button" :class="{ active: menuActive }">
      <div class="editor-drag-handle__button-content">
        <i class="i-ri-draggable editor-drag-handle__icon" />
      </div>
    </div>

    <template #menu>
      <DropdownItem>
        <template #icon>
          <i class="i-ri-text-wrap editor-drag-handle__menu-icon" />
        </template>
        切换格式
        <template #submenu>
          <DropdownSubmenu>
            <DropdownItem command="paragraph" @click="handleSetParagraph">
              <template #icon>
                <i class="i-ri-paragraph editor-drag-handle__menu-icon" />
              </template>
              正文
            </DropdownItem>
            <DropdownItem>
              <template #icon>
                <i class="i-ri-font-size editor-drag-handle__menu-icon" />
              </template>
              标题
              <template #submenu>
                <DropdownSubmenu>
                  <DropdownItem
                    v-for="level in 6"
                    :key="`heading-${level}`"
                    :command="`heading-${level}`"
                    @click="() => handleSetHeading(level)"
                  >
                    <template #icon>
                      <i class="i-ri-text editor-drag-handle__menu-icon" />
                    </template>
                    标题{{ level }}
                  </DropdownItem>
                </DropdownSubmenu>
              </template>
            </DropdownItem>
            <DropdownItem command="orderedList" @click="handleSetOrderedList">
              <template #icon>
                <i class="i-ri-list-ordered editor-drag-handle__menu-icon" />
              </template>
              有序列表
            </DropdownItem>
            <DropdownItem command="bulletList" @click="handleSetBulletList">
              <template #icon>
                <i class="i-ri-list-unordered editor-drag-handle__menu-icon" />
              </template>
              无序列表
            </DropdownItem>
            <DropdownItem command="blockquote" @click="handleSetBlockquote">
              <template #icon>
                <i class="i-ri-quote-text editor-drag-handle__menu-icon" />
              </template>
              引用
            </DropdownItem>
          </DropdownSubmenu>
        </template>
      </DropdownItem>

      <DropdownItem command="clearFormat" @click="handleClearFormat">
        <template #icon>
          <i class="i-ri-format-clear editor-drag-handle__menu-icon" />
        </template>
        清除格式
      </DropdownItem>

      <DropdownItem command="copyNode" @click="handleCopyNode">
        <template #icon>
          <i class="i-ri-file-copy-line editor-drag-handle__menu-icon" />
        </template>
        复制节点
      </DropdownItem>

      <DropdownItem command="copy" divided @click="handleCopy">
        <template #icon>
          <i class="i-ri-file-copy-2-line editor-drag-handle__menu-icon" />
        </template>
        复制
      </DropdownItem>

      <DropdownItem command="cut" @click="handleCut">
        <template #icon>
          <i class="i-ri-scissors-line editor-drag-handle__menu-icon" />
        </template>
        剪切
      </DropdownItem>

      <DropdownItem command="delete" @click="handleDelete">
        <template #icon>
          <i class="i-ri-delete-bin-line editor-drag-handle__menu-icon" />
        </template>
        删除
      </DropdownItem>
    </template>
  </DropdownMenu>
</template>

<script setup lang="ts">
import { inject, ref, nextTick } from "vue";
import type { Node } from "@tiptap/pm/model";
import { DropdownMenu, DropdownItem, DropdownSubmenu } from "../../../dropdown";
import { useClipboard } from "@vueuse/core";

defineOptions({
  name: "DragHandleButton",
});

const editor = inject<any>("editor");
const blockMenu = inject<any>("blockMenu");

const menuActive = ref(false);
const { copy: copyToClipboard } = useClipboard();

const props = defineProps<{
  node?: Node | null;
  pos?: number | null;
}>();

const emits = defineEmits<{
  dropdownVisible: [visible: boolean];
}>();

const handleMenuVisibleChange = (visible: boolean) => {
  editor.value.commands.focus();
  menuActive.value = visible;
  blockMenu.value = visible;
  emits("dropdownVisible", visible);

  // 菜单关闭时，强制隐藏所有子菜单（包括二级和三级菜单）
  if (!visible) {
    // 使用 nextTick 确保 DOM 已更新
    nextTick(() => {
      // 先隐藏所有三级菜单
      const allNestedSubmenus = document.querySelectorAll(".submenu .submenu");
      allNestedSubmenus.forEach((submenu) => {
        (submenu as HTMLElement).style.setProperty(
          "display",
          "none",
          "important"
        );
      });
      // 然后隐藏所有二级菜单
      const allSubmenus = document.querySelectorAll(".submenu");
      allSubmenus.forEach((submenu) => {
        // 确保不是三级菜单（三级菜单已经被隐藏）
        if (!submenu.querySelector(".submenu")) {
          (submenu as HTMLElement).style.setProperty(
            "display",
            "none",
            "important"
          );
        }
      });
    });
  }
};

// 切换格式处理函数
const handleSetParagraph = () => {
  if (!editor?.value) return;
  editor.value.chain().focus().setParagraph().run();

  // 点击后关闭所有子菜单（包括二级和三级菜单）
  nextTick(() => {
    // 先隐藏所有三级菜单
    const allNestedSubmenus = document.querySelectorAll(".submenu .submenu");
    allNestedSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
    // 然后隐藏所有二级菜单
    const allSubmenus = document.querySelectorAll(".submenu");
    allSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
  });
};

// 设置标题
const handleSetHeading = (level: number) => {
  if (!editor?.value) return;
  // 先取消其他列表格式
  if (editor.value.isActive("orderedList")) {
    editor.value.chain().focus().toggleOrderedList().run();
  }
  if (editor.value.isActive("bulletList")) {
    editor.value.chain().focus().toggleBulletList().run();
  }
  if (editor.value.isActive("blockquote")) {
    editor.value.chain().focus().toggleBlockquote().run();
  }
  editor.value
    .chain()
    .focus()
    .setHeading({ level: level as 1 | 2 | 3 | 4 | 5 | 6 })
    .run();

  // 点击后关闭所有子菜单（包括二级和三级菜单）
  nextTick(() => {
    // 先隐藏所有三级菜单
    const allNestedSubmenus = document.querySelectorAll(".submenu .submenu");
    allNestedSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
    // 然后隐藏所有二级菜单
    const allSubmenus = document.querySelectorAll(".submenu");
    allSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
  });
};

const handleSetOrderedList = () => {
  if (!editor?.value) return;
  // 如果不是有序列表，则切换为有序列表；如果已经是，则切换为段落
  if (editor.value.isActive("orderedList")) {
    editor.value.chain().focus().toggleOrderedList().run();
  } else {
    // 先取消其他列表格式
    if (editor.value.isActive("bulletList")) {
      editor.value.chain().focus().toggleBulletList().run();
    }
    if (editor.value.isActive("blockquote")) {
      editor.value.chain().focus().toggleBlockquote().run();
    }
    editor.value.chain().focus().toggleOrderedList().run();
  }

  // 点击后关闭所有子菜单（包括二级和三级菜单）
  nextTick(() => {
    // 先隐藏所有三级菜单
    const allNestedSubmenus = document.querySelectorAll(".submenu .submenu");
    allNestedSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
    // 然后隐藏所有二级菜单
    const allSubmenus = document.querySelectorAll(".submenu");
    allSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
  });
};

const handleSetBulletList = () => {
  if (!editor?.value) return;
  // 如果不是无序列表，则切换为无序列表；如果已经是，则切换为段落
  if (editor.value.isActive("bulletList")) {
    editor.value.chain().focus().toggleBulletList().run();
  } else {
    // 先取消其他列表格式
    if (editor.value.isActive("orderedList")) {
      editor.value.chain().focus().toggleOrderedList().run();
    }
    if (editor.value.isActive("blockquote")) {
      editor.value.chain().focus().toggleBlockquote().run();
    }
    editor.value.chain().focus().toggleBulletList().run();
  }

  // 点击后关闭所有子菜单（包括二级和三级菜单）
  nextTick(() => {
    // 先隐藏所有三级菜单
    const allNestedSubmenus = document.querySelectorAll(".submenu .submenu");
    allNestedSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
    // 然后隐藏所有二级菜单
    const allSubmenus = document.querySelectorAll(".submenu");
    allSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
  });
};

const handleSetBlockquote = () => {
  if (!editor?.value) return;
  // 如果不是引用，则切换为引用；如果已经是，则切换为段落
  if (editor.value.isActive("blockquote")) {
    editor.value.chain().focus().toggleBlockquote().run();
  } else {
    // 先取消其他列表格式
    if (editor.value.isActive("orderedList")) {
      editor.value.chain().focus().toggleOrderedList().run();
    }
    if (editor.value.isActive("bulletList")) {
      editor.value.chain().focus().toggleBulletList().run();
    }
    editor.value.chain().focus().toggleBlockquote().run();
  }

  // 点击后关闭所有子菜单（包括二级和三级菜单）
  nextTick(() => {
    // 先隐藏所有三级菜单
    const allNestedSubmenus = document.querySelectorAll(".submenu .submenu");
    allNestedSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
    // 然后隐藏所有二级菜单
    const allSubmenus = document.querySelectorAll(".submenu");
    allSubmenus.forEach((submenu) => {
      (submenu as HTMLElement).style.setProperty(
        "display",
        "none",
        "important"
      );
    });
  });
};

// 清除格式
const handleClearFormat = () => {
  if (!editor?.value) return;

  const { state } = editor.value;
  const { selection } = state;

  // 如果没有选中文本，选中当前段落
  if (selection.empty) {
    editor.value.commands.selectAll();
  }

  editor.value
    ?.chain()
    .setNodeSelection(props.pos)
    .focus()
    .unsetAllMarks()
    .run();
};

// 复制节点
const handleCopyNode = () => {
  if (
    !editor?.value ||
    !props.node ||
    props.pos === null ||
    props.pos === undefined
  )
    return;

  const { state, view } = editor.value;

  // 尝试直接从 DOM 获取节点
  const domNode = view.nodeDOM(props.pos);
  if (domNode && domNode instanceof HTMLElement) {
    copyToClipboard(domNode.outerHTML);
    return;
  }

  // 如果无法获取 DOM，使用 JSON 格式
  try {
    const nodeSize = props.node.nodeSize;
    const from = props.pos;
    const to = props.pos + nodeSize;
    const nodeSlice = state.doc.slice(from, to);
    const jsonContent = nodeSlice.content.toJSON();

    // 直接复制节点文本内容或 JSON
    const textContent = props.node.textContent || JSON.stringify(jsonContent);
    copyToClipboard(textContent);
  } catch (error) {
    console.warn("Failed to copy node:", error);
    // 最后的降级方案：复制节点文本内容
    const textContent = props.node.textContent || props.node.type.name;
    copyToClipboard(textContent);
  }
};

// 复制选中内容
const handleCopy = () => {
  if (!editor?.value) return;

  const { state } = editor.value;
  const { selection } = state;

  if (selection.empty) {
    // 如果没有选中内容，复制当前节点
    handleCopyNode();
    return;
  }

  // 使用浏览器原生的复制命令（最可靠的方法）
  try {
    // TipTap 编辑器已经处理了复制事件，直接触发即可
    document.execCommand("copy");
  } catch (error) {
    console.warn("Failed to copy selection:", error);
    // 如果 execCommand 失败，尝试使用剪贴板 API
    const selectedText = state.doc.textBetween(selection.from, selection.to);
    if (selectedText) {
      copyToClipboard(selectedText);
    }
  }
};

// 剪切选中内容
const handleCut = () => {
  if (!editor?.value) return;

  const { state } = editor.value;
  const { selection } = state;

  // 先复制
  handleCopy();

  // 然后删除选中内容
  if (!selection.empty) {
    editor.value.chain().focus().deleteSelection().run();
  } else if (props.node && props.pos !== null && props.pos !== undefined) {
    // 如果选中的是节点，删除节点
    const nodeSize = props.node.nodeSize;
    const from = props.pos;
    const to = props.pos + nodeSize;
    editor.value.chain().focus().deleteRange({ from, to }).run();
  }
};

// 删除节点
const handleDelete = () => {
  if (
    !editor?.value ||
    !props.node ||
    props.pos === null ||
    props.pos === undefined
  )
    return;

  const nodeSize = props.node.nodeSize;
  const from = props.pos;
  const to = props.pos + nodeSize;

  editor.value.chain().focus().deleteRange({ from, to }).run();
};
</script>

<style lang="scss" scoped>
.editor-drag-handle__button {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: var(--editor-page-background);
  color: var(--editor-text-color-light) !important;
  cursor: grab;

  &:active {
    cursor: grabbing;
  }

  .editor-drag-handle__button-content {
    color: rgba(0, 0, 0, 0.5);
  }

  &:not(.active):hover {
    background-color: var(--editor-content-node-selected-background);
  }

  &.active {
    &:hover {
      opacity: 0.8;
    }
    .editor-drag-handle__button-content {
      color: var(--editor-text-color-light);
    }
  }

  .editor-drag-handle__icon {
    width: 16px;
    height: 16px;
    display: inline-block;
  }
}

.editor-drag-handle__popover-menu {
  min-width: 120px;
  padding: 4px 0;
}

.editor-drag-handle__menu-item {
  display: flex;
  align-items: center;
  padding: 8px 16px;
  cursor: pointer;
  transition: background-color 0.2s;

  &:hover {
    background-color: var(--editor-content-node-selected-background);
  }

  &--danger {
    color: var(--editor-error-color);

    &:hover {
      background-color: var(--editor-error-color-light);
    }
  }
}

// 删除项的危险样式（最后一个带分隔线的项）
:deep(.popup-menu .dropdown-item.dropdown-divider:last-of-type) {
  color: var(--editor-error-color);

  &:hover {
    background-color: var(--editor-error-color-light);
  }

  .dropdown-item-content,
  .dropdown-item-icon {
    color: var(--editor-error-color);
  }
}

.editor-drag-handle__menu-icon {
  width: 16px;
  height: 16px;
  margin-right: 8px;
  font-size: 16px;
}
</style>
